import { useAuthStore } from '@/store/auth'

// API 基础配置
const BASE_URL = 'http://localhost:5000'
const TIMEOUT = 30000

// 响应状态码
export const CODE = {
  SUCCESS: 200,
  BAD_REQUEST: 400,
  UNAUTHORIZED: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
  LOGIN_FAILED: 1001,
  TOKEN_INVALID: 1002,
  USER_NOT_FOUND: 1003,
  PERMISSION_DENIED: 1004,
  VALIDATION_FAILED: 1005
}

/**
 * 创建请求实例
 */
class Request {
  constructor() {
    this.baseURL = BASE_URL
    this.timeout = TIMEOUT
  }

  /**
   * 检查并处理 token 过期
   */
  checkTokenExpired() {
    const authStore = useAuthStore()

    // 检查 token 是否过期
    if (authStore.isTokenExpired()) {
      // 清除登录状态
      authStore.logout()

      // 跳转到登录页
      if (window.location.pathname !== '/login') {
        window.location.href = '/login'
      }

      throw new Error('登录已过期,请重新登录')
    }
  }

  /**
   * 设置请求头
   */
  getHeaders(customHeaders = {}) {
    const headers = {
      'Content-Type': 'application/json',
      ...customHeaders
    }

    // 添加 token
    const token = localStorage.getItem('access_token')
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }

    return headers
  }

  /**
   * 处理响应
   */
  async handleResponse(response) {
    // 检查响应内容类型
    const contentType = response.headers.get('content-type')

    // 如果不是 JSON 响应，尝试获取文本内容
    if (!contentType || !contentType.includes('application/json')) {
      const text = await response.text()
      console.error('非 JSON 响应:', text)
      throw new Error('服务器返回格式错误，请检查后端 API 是否正确实现')
    }

    let data
    try {
      data = await response.json()
    } catch (error) {
      console.error('JSON 解析失败:', error)
      throw new Error('响应数据解析失败')
    }

    // 响应成功 - 统一格式: { code: 200, message: "", data: {} }
    if (data.code === CODE.SUCCESS) {
      return data
    }

    // token 失效，清除登录状态
    if (response.status === 401 || data.code === CODE.UNAUTHORIZED || data.code === CODE.TOKEN_INVALID) {
      localStorage.removeItem('access_token')
      const authStore = useAuthStore()
      authStore.logout()

      // 跳转到登录页
      if (window.location.pathname !== '/login') {
        window.location.href = '/login'
      }
    }

    // 抛出错误
    throw new Error(data.message || '请求失败')
  }

  /**
   * 处理请求错误
   */
  handleError(error) {
    console.error('请求错误:', error)

    if (error.name === 'AbortError') {
      throw new Error('请求超时')
    }

    if (!navigator.onLine) {
      throw new Error('网络连接失败，请检查网络设置')
    }

    throw error
  }

  /**
   * GET 请求
   */
  async get(url, params = {}, options = {}) {
    // 检查 token 是否过期(跳过不需要认证的接口)
    if (localStorage.getItem('access_token') && !url.includes('/auth/login') && !url.includes('/auth/register')) {
      this.checkTokenExpired()
    }

    const queryString = new URLSearchParams(params).toString()
    const fullUrl = `${this.baseURL}${url}${queryString ? '?' + queryString : ''}`

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(fullUrl, {
        method: 'GET',
        headers: this.getHeaders(options.headers),
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.handleResponse(response)
    } catch (error) {
      clearTimeout(timeoutId)
      return this.handleError(error)
    }
  }

  /**
   * POST 请求
   */
  async post(url, data = {}, options = {}) {
    // 检查 token 是否过期(跳过不需要认证的接口)
    if (localStorage.getItem('access_token') && !url.includes('/auth/login') && !url.includes('/auth/register')) {
      this.checkTokenExpired()
    }

    const fullUrl = `${this.baseURL}${url}`

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(fullUrl, {
        method: 'POST',
        headers: this.getHeaders(options.headers),
        body: JSON.stringify(data),
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.handleResponse(response)
    } catch (error) {
      clearTimeout(timeoutId)
      return this.handleError(error)
    }
  }

  /**
   * PUT 请求
   */
  async put(url, data = {}, options = {}) {
    // 检查 token 是否过期
    if (localStorage.getItem('access_token')) {
      this.checkTokenExpired()
    }

    const fullUrl = `${this.baseURL}${url}`

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(fullUrl, {
        method: 'PUT',
        headers: this.getHeaders(options.headers),
        body: JSON.stringify(data),
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.handleResponse(response)
    } catch (error) {
      clearTimeout(timeoutId)
      return this.handleError(error)
    }
  }

  /**
   * DELETE 请求
   */
  async delete(url, options = {}) {
    // 检查 token 是否过期
    if (localStorage.getItem('access_token')) {
      this.checkTokenExpired()
    }

    const fullUrl = `${this.baseURL}${url}`

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(fullUrl, {
        method: 'DELETE',
        headers: this.getHeaders(options.headers),
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.handleResponse(response)
    } catch (error) {
      clearTimeout(timeoutId)
      return this.handleError(error)
    }
  }

  /**
   * 文件上传请求
   * @param {string} url - 请求路径
   * @param {FormData} formData - 表单数据
   * @param {Object} options - 可选配置
   * @returns {Promise<Object>} 响应数据
   */
  async upload(url, formData, options = {}) {
    // 检查 token 是否过期
    if (localStorage.getItem('access_token')) {
      this.checkTokenExpired()
    }

    const fullUrl = `${this.baseURL}${url}`

    // 获取基础 headers，但不设置 Content-Type (让浏览器自动设置 multipart/form-data)
    const headers = {}
    const token = localStorage.getItem('access_token')
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(fullUrl, {
        method: 'POST',
        headers: { ...headers, ...options.headers },
        body: formData,
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.handleResponse(response)
    } catch (error) {
      clearTimeout(timeoutId)
      return this.handleError(error)
    }
  }
}

// 创建请求实例
const request = new Request()

export default request